import { restfulClient } from '@/api'
import { uniq } from '@/utils/lodash/Array'
/**
 * RPC风格
 */
const rpcModule = {
  state: {
    path: '',
    defaultRels: [],
    defaultQuery: {},
    collection: {
      collection: [],
      meta: { total: 0 }
    },
    document: {
      document: {},
      meta: {}
    },
    excelList: {},
    form: {},
    filter: {}
  },
  getters: {
    collection: state => state.collection.collection,
    pagination: state => state.collection.meta ? state.collection.meta.pagination : { limit: 10, currentPage: 1 },
    total: state => state.collection.meta ? state.collection.meta.total : 0,
    document: state => state.document.document
  },
  mutations: {
    setCollection(state, collection) {
      state.collection = collection
    },
    setDocument(state, document) {
      state.document = document
    },
    setForm(state, form) {
      state.form = form
    },
    addForm(state, form) {
      state.form = { ...state.form, ...form }
    },
    setFilter(state, filter) {
      state.filter = filter
    }
  },
  actions: {
    /**
     * @param {QueryParams} queryParams
     */
    async find({ state }, queryParams = {}) {
      const { all = false } = queryParams
      queryParams.query = { ...state.defaultQuery, ...queryParams.query }
      queryParams.withRels = uniq([...(queryParams.withRels || []), ...state.defaultRels])
      return all ? restfulClient.getAll(state.path, queryParams) : restfulClient.getCollection(state.path, queryParams)
    },
    /**
     * @param {QueryParams} queryParams
     */
    async collection({ commit, dispatch, state }, queryParams = {}) {
      const { data } = await dispatch('find', queryParams)
      commit('setCollection', data)
      return state.collection
    },
    /**
     * @param {QueryParams} queryParams
     */
    async allCollection({ commit, dispatch, state }, queryParams = {}) {
      const { data } = await dispatch('find', { ...queryParams, all: true })
      commit('setCollection', data)
      return state.collection
    },
    async document({ commit, state }, { id, withRels = [] }) {
      withRels = lodash.uniq([...withRels, ...state.defaultRels])
      const { data } = await restfulClient.getDocument(state.path, id, withRels)
      commit('setDocument', data)
      return state.document
    },
    async create({ state }, data) {
      return restfulClient.create(state.path, data)
    },
    async batchCreate({ state }, dataArray) {
      return restfulClient.batchCreate(state.path, dataArray)
    },
    async update({ state }, data) {
      const { id, ...props } = data
      return restfulClient.update(state.path, id, props)
    },
    async replace({ state }, data) {
      const { id, ...props } = data
      return restfulClient.replace(state.path, id, props)
    },
    async remove({ state }, data) {
      const { id } = data
      return restfulClient.remove(state.path, id)
    },
    /**
     * @param {QueryParams} queryParams
     * @param {array} data
     */
    async batchUpdate({ state }, { queryParams, data }) {
      return restfulClient.batchUpdate(state.path, queryParams, data)
    }
  }
}

const moduleProps = ['state', 'getters', 'mutations', 'actions']
export default function createRpcModule(module, namespaced = true) {
  module.namespaced = namespaced
  moduleProps.forEach(prop => {
    module[prop] = { ...rpcModule[prop], ...(module[prop] || {}) }
  })
  return module
}
